package br.com.automed.entity;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;

@Entity
@Table(name="CM_USUARIO")
@NamedQueries({
	@NamedQuery(name="Usuario.findByCpf", query="select o from Usuario o where o.cpf = :cpf"),
	@NamedQuery(name="Usuario.findByUsuarioSenha", query="select o from Usuario o where o.login = :login and o.senha = :senha"),
	@NamedQuery(name="Usuario.findAdministradores", query="select o from Usuario o where o.perfil.tipoPerfil = :perfilADM"),
	@NamedQuery(name="Usuario.findUsuarioByEmail", query="select o from Usuario o where o.email = :emailUsuario")
})
@Inheritance(strategy=InheritanceType.JOINED)
public class Usuario {
	
	public static final String NAMED_QUERY_FIND_USUARIO_BY_CPF	= "Usuario.findByCpf";
	public static final String NAMED_QUERY_FIND_USUARIO 		= "Usuario.findByUsuarioSenha";
	public static final String NAMED_QUERY_FIND_ADMINISTRADORES = "Usuario.findAdministradores";
	
	@Id
    @GeneratedValue(generator = "system-uuid", strategy=GenerationType.AUTO)
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    @Column(name = "ID_USUARIO")
	private String idUsuario;
	
	@Column(name = "ST_USUARIO")
	private String nome;
	
	@Column(name = "ST_CPF")
	private String cpf;

	@Column(name = "ST_RG")
	private String rg;
	
	@Column(name = "ST_LOGIN")
	private String login;

	@Column(name = "ST_SENHA")
	private String senha;

	@Transient
	private String confirmaSenha;
	
	@Column(name = "ST_EMAIL")
	private String email;

	@Column(name = "NR_ACESSO")
	private Integer num_acessos;
	
	@ManyToOne()
	@JoinColumn(name="FK_PERFIL", referencedColumnName="ID_PERFIL")
	private Perfil perfil;
	
	//trazer telefones com NamedQuery
	@ManyToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @JoinTable(name="CM_TELEFONE_USUARIO",
    joinColumns=@JoinColumn(name="ID_USUARIO"),
    inverseJoinColumns=@JoinColumn(name="ID_TELEFONE"))
    @LazyCollection(LazyCollectionOption.FALSE)
	private List<Telefone> telefones;
	
	@OneToOne(cascade=CascadeType.ALL)
	@JoinColumn(name="FK_ENDERECO", referencedColumnName="ID_ENDERECO")
	private Endereco endereco;
	
	@Transient
	private Date dataAcesso;
	
	public Usuario() {
		perfil = new Perfil();
		endereco = new Endereco();
		telefones = new ArrayList<Telefone>();
		dataAcesso = new Date();
	}

	public String getIdUsuario() {
		return idUsuario;
	}

	public void setIdUsuario(String idUsuario) {
		this.idUsuario = idUsuario;
	}

	public String getNome() {
		return nome;
	}

	public void setNome(String nome) {
		this.nome = nome;
	}

	public String getCpf() {
		return cpf;
	}

	public void setCpf(String cpf) {
		this.cpf = cpf;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getRg() {
		return rg;
	}

	public void setRg(String rg) {
		this.rg = rg;
	}

	public String getLogin() {
		return login;
	}

	public void setLogin(String login) {
		this.login = login;
	}

	public String getSenha() {
		return senha;
	}

	public void setSenha(String senha) {
		this.senha = senha;
	}

	public String getConfirmaSenha() {
		return confirmaSenha;
	}

	public void setConfirmaSenha(String confirmaSenha) {
		this.confirmaSenha = confirmaSenha;
	}

	public Integer getNum_acessos() {
		return num_acessos;
	}

	public void setNum_acessos(Integer num_acessos) {
		this.num_acessos = num_acessos;
	}

	public Perfil getPerfil() {
		return perfil;
	}

	public void setPerfil(Perfil perfil) {
		this.perfil = perfil;
	}

	public List<Telefone> getTelefones() {
		return telefones;
	}

	public void setTelefones(List<Telefone> telefones) {
		this.telefones = telefones;
	}

	public Endereco getEndereco() {
		return endereco;
	}

	public void setEndereco(Endereco endereco) {
		this.endereco = endereco;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((idUsuario == null) ? 0 : idUsuario.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Usuario other = (Usuario) obj;
		if (idUsuario == null) {
			if (other.idUsuario != null)
				return false;
		} else if (!idUsuario.equals(other.idUsuario))
			return false;
		return true;
	}

	public Date getDataAcesso() {
		return dataAcesso;
	}

	public void setDataAcesso(Date dataAcesso) {
		this.dataAcesso = dataAcesso;
	}
	
}
